﻿using System;
using System.Security;
using System.Security.Principal;
using Tangosol.IO.Pof;
using Tangosol.Net;
using System.IdentityModel.Tokens;
using System.Threading;

namespace Coherence.Patterns.Security
{
    public class KerberosTokenPrincipal : IPrincipal, IPortableObject
    {
        private String spn;

        public KerberosTokenPrincipal()
        {
            init();
        }

        public KerberosTokenPrincipal(String spn)
        {
            this.spn = spn;
            init();
        }

        private void init()
        {
        }

        #region IPortableObject Members

        public void ReadExternal(IPofReader reader)
        {
            reader.ReadByteArray(0); // value is ignored
            reader.ReadString(1);    // value is ignored
            String spn = reader.ReadString(2);
            reader.ReadString(3);   // value is ignored
        }

        public void WriteExternal(IPofWriter writer)
        {
            String serviceName;
            IPofContext pofContext = writer.PofContext;
            if (pofContext is KerberosPofSerializer)
            {
                KerberosPofSerializer krbSerializer = (KerberosPofSerializer)pofContext;
                if (krbSerializer.Spn == null || krbSerializer.Spn.Trim().Length == 0)
                {
                    throw new SecurityException("The spn parameter of the KerberosPofSerializer has not been set");
                }
                serviceName = krbSerializer.Spn;
            } 
            else 
            {
                serviceName = spn;
                if (spn == null && spn.Trim().Length == 0)
                {
                    throw new SecurityException("The spn for this KerberosTokenPrincipal is not set");
                }
            }


            KerberosRequestorSecurityToken token = new KerberosRequestorSecurityToken(serviceName);
            WindowsIdentity windowsID = WindowsIdentity.GetCurrent();

            writer.WriteByteArray(0, token.GetRequest());
            writer.WriteString(1, windowsID.Name);
            writer.WriteString(2, spn);
            writer.WriteString(3, ".Net Client");
        }

        #endregion

        #region IPrincipal Members

        public System.Security.Principal.IIdentity Identity
        {
            get
            {
                return null;
            }
        }

        public bool IsInRole(string role)
        {
            return false;
        }

        #endregion
    }
}
